﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.IO;
using System.Reflection;
using KC.DataAccess.Processor;

namespace KC.Business.Processor
{
	public class Processor
	{
		public static List<ProcessorBase> GetProcessors()
		{
			List<ProcessorBase> result = new List<ProcessorBase>();
			string assies = new FileInfo(System.Reflection.Assembly.GetAssembly(typeof(ProcessorBase)).Location).DirectoryName;
			foreach (string dll in Directory.GetFiles(assies, "*.dll"))
				foreach (Type type in Assembly.LoadFile(dll).GetTypes())
					try {
						if (type.IsSubclassOf(typeof(ProcessorBase)))
							result.Add((ProcessorBase)Activator.CreateInstance(type)); }
					catch (Exception ex) { LogError(ex); }
			return result;
		}
		public static List<DisplayPluginBase> GetDisplayPlugins(string path)
		{
			List<DisplayPluginBase> result = new List<DisplayPluginBase>();
			foreach (string dll in Directory.GetFiles(path))
				try {
					foreach (Type type in Assembly.LoadFile(dll).GetTypes())
						try {
							if (type.IsSubclassOf(typeof(DisplayPluginBase)))
								result.Add((DisplayPluginBase)Activator.CreateInstance(type)); }
						catch (Exception ex) { LogError(ex); } }
				catch (BadImageFormatException) { }
				catch (NotSupportedException) { }
			return result;
		}

		public static List<ProcessorBase> GetScheduledProcessors(ref ProcessorDataContext dc, List<ProcessorBase> processors)
		{
			List<ProcessorBase> result = new List<ProcessorBase>();
			foreach (Schedule sched in dc.Schedules.ToList())
				foreach (ProcessorBase processor in processors)
					if (sched.Name == processor.GetType().Name) {
						result.Add(processor);
						break; }
			return result;
		}

		public static object GetSetting(string name)
		{
			using (ProcessorDataContext dc = new ProcessorDataContext()) {
				var values = from v in dc.Values where v.Setting.Name == name select v;
				if (values.Count() == 0) return null;
				Value val = values.First();

				try { return Convert.ChangeType(val.Value1, Type.GetType(val.Setting.Type)); }
				catch { return val.Value1; } }
		}
		public static List<object> GetSettings(string name)
		{
			List<object> result = new List<object>();
			using (ProcessorDataContext dc = new ProcessorDataContext()) {
				var values = from v in dc.Values where v.Setting.Name == name select v;
				
				foreach (Value val in values) 
					try { result.Add(Convert.ChangeType(val.Value1, Type.GetType(val.Setting.Type))); }
					catch { result.Add(val.Value1); } }
			return result;
		}

		public static void LogError(Exception ex)
		{
			try
			{
				using (ProcessorDataContext dc = new ProcessorDataContext(System.Configuration.ConfigurationManager.ConnectionStrings["Processor"].ConnectionString))
				{
					dc.Errors.InsertOnSubmit(new Error() { Datetime = DateTime.Now, ExType = ex.GetType().Name, Message = ex.Message, StackTrace = ex.StackTrace ?? Environment.StackTrace });
					dc.SubmitChanges();
				}
			}
			catch { }
		}
		public static void LogError(string ex)
		{
			try
			{
				using (ProcessorDataContext dc = new ProcessorDataContext(System.Configuration.ConfigurationManager.ConnectionStrings["Processor"].ConnectionString))
				{
					dc.Errors.InsertOnSubmit(new Error() { Datetime = DateTime.Now, ExType = ex.GetType().Name, Message = ex, StackTrace = Environment.StackTrace });
					dc.SubmitChanges();
				}
			}
			catch { }
		}
		public static void AddDetail(ref ProcessorDataContext dc, string msg)
		{
			msg = msg.Trim() + "\r\n";
			dc.Details.InsertOnSubmit(new Detail() { datetime = DateTime.Now, text = msg });
			dc.SubmitChanges();
		}

	}
}
